package com.company;

/**
 * @date : 2021-11-29 下午11:05
 * https://www.jianshu.com/p/20bd2e9b1f03
 * https://www.jianshu.com/p/8ccdd665411f
 */
public class P004_Concurrency {

    public static class ConcurrencyTest {

        // 累加次数
        private static final long COUNT = 10000L;

        public static void main(String[] args) throws InterruptedException {
            concurrency();
            serial();
        }

        /**
         * 多线程累加
         *
         * @throws InterruptedException
         */
        private static void concurrency() throws InterruptedException {
            long start = System.currentTimeMillis();

            // 启动新线程执行运行操作
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    int a = 0;
                    for (int i = 0; i < COUNT; i++) {
                        a += 5;
                    }
                }
            });
            thread.start();

            int b = 0;
            for (int i = 0; i < COUNT; i++) {
                b--;
            }
            // 等线程执行完
            thread.join();
            long end = System.currentTimeMillis() - start;
            System.out.println("concurrency 总共耗时" + end);
        }

        /**
         * 单线程累加
         */
        private static void serial() {
            long start = System.currentTimeMillis();
            int a = 0;
            for (int i = 0; i < COUNT; i++) {
                a += 5;
            }
            int b = 0;
            for (int i = 0; i < COUNT; i++) {
                b--;
            }
            long end = System.currentTimeMillis() - start;
            System.out.println("serial 总共耗时" + end);
        }
    }


    public static class SyncExample5 {

        static boolean flag = true;

        // 锁对象
        static Object lock = new Object();

        public static void main(String[] args) throws InterruptedException {

            // 线程一
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (flag) {
                        // 默认不可见，死循环，放开以下注释即可解决不可见操作

                        // 方式一，加上sycn操作即可解决可见性问题
                        synchronized (lock){}

                        // 方式二, println 方法实现加上了同步机制，保证每次输出都是最新值
                        // System.out.println(flag);
                    }
                }
            }).start();

            // 睡眠两秒
            Thread.sleep(2000L);

            // 线程二
            new Thread(new Runnable() {
                @Override
                public void run() {
                    flag = false;
                    System.out.println("flag 值已修改");
                }
            }).start();
        }
    }


}
